﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Optimus
{
   public unsafe class NovaDraw2D 
    {
   
       public static void DrawTextChar(uint x, uint y, byte[] Data, uint Color)
        {
            int c = 0;
            for (uint p = y; p < y + 9; p++)
            {
                for (uint i = x; i < x + 5; i++)
                {
                    if (Data[c] == 1)
                    {
                        VGA.dbuffer[(p * VGA.ScreenWidth) + i] = Color;
                    }

                    c = c + 1;
                }
            }
        }

       public static void DrawScreen()
       {
           for (int y = 0; y < VGA.ScreenHeight; y++)
           {
               for (int x = 0; x < VGA.ScreenWidth; x++)
               {

                   VGA.SetPixel((uint)x, (uint)y, VGA.dbuffer[(y * VGA.ScreenWidth) + x]);
               }

           }
       }

       public static void DrawTextCharEx(uint x, uint y, byte[] Data, uint Color)
       {
           int c = 0;
           for (uint p = y; p < y + 7; p++)
           {
               for (uint i = x; i < x + 5; i++)
               {
                   if (Data[c] == 1)
                   {
                       VGA.dbuffer[(p * VGA.ScreenWidth) + i] = Color;
                   }

                   c = c + 1;
               }
           }
         }

        public static void DrawHorizontalLine(uint x, uint y, uint Length, uint Thickness, byte Color)
        {
            for (uint i = x; i < x + Length; i++)
            {
                for (uint p = y; p < y + Thickness; p++)
                {
                    VGA.dbuffer[(p * VGA.ScreenWidth) + i] = Color;
                }
            }
        }

        public static void DrawVerticalLine(uint x, uint y, uint Length, uint Thickness, byte Color)
        {
            for (uint i = x; i < x + Thickness; i++)
            {
                for (uint p = y; p < y + Length; p++)
                {
                    VGA.dbuffer[(p * VGA.ScreenWidth) + i] = Color;
                }
            }
        }

        public static void DrawSquare(uint x, uint y, uint Size, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            p = y;
            for (uint i = x; i <= x + Size; i++)
            {
                VGA.dbuffer[(y * VGA.ScreenWidth) + i] = Color;
                VGA.dbuffer[(( y + Size) * VGA.ScreenWidth) + i] = Color;
                VGA.dbuffer[(p * VGA.ScreenWidth) + x] = Color;
                VGA.dbuffer[(p * VGA.ScreenWidth) + (x + Size)] = Color;
                p = p + 1;
            }

        }

        public static void DrawFillSquare(uint x, uint y, uint Size, byte Color)
        {
            //TODO: Use One Loop to improve speed

            for (uint j = y; j <= y + Size; j++)
            {
                for (uint i = x; i < x + Size; i++)
                {
                    VGA.dbuffer[(j * VGA.ScreenWidth) + i] = Color;
                }

            }
        }

        public static void DrawFillRectangle(uint x, uint y, uint xSize, uint ySize, uint Color)
        {
          
            //TODO: Use One Loop to improve speed
            for (uint y1 = y; y1 < y + ySize; y1++)
            {
                for (uint x1 = x; x1 < x + xSize; x1++)
                {
                    VGA.dbuffer[(y1 * VGA.ScreenWidth) + x1] = Color;
                }

            }
        }

        public static void DrawRectangle(uint x, uint y, uint xSize, uint ySize, byte Color)
        {
            //Use One Loop to improve speed
            for (uint i = x; i < x + xSize; i++)
            {
                VGA.dbuffer[(y * VGA.ScreenWidth) + i] = Color;
                VGA.dbuffer[((y + ySize) * VGA.ScreenWidth) + i] = Color;
            }
            for (uint i = y; i <= y + ySize; i++)
            {
                VGA.dbuffer[(i * VGA.ScreenWidth) + x] = Color;
                VGA.dbuffer[(i * VGA.ScreenWidth) + (x + xSize)] = Color;
            }
        }

        public static void DrawEQTriangleDown(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint cst = Base / 2;
            uint rsy = y;
            uint rsx = x + Base;
            uint lsy = y;
            uint lsx = x;

            for (uint i = x; i <= x + Base; i++)
            {
                lsy = lsy - 1;
                lsx = lsx + 1;
                rsy = rsy - 1;
                rsx = rsx - 1;
                VGA.dbuffer[(y * VGA.ScreenWidth) + i] = Color;
                if (p != cst)
                {
                    VGA.dbuffer[(lsy * VGA.ScreenWidth) + lsx] = Color;
                    VGA.dbuffer[(rsy * VGA.ScreenWidth) + rsx] = Color;
                    p = p + 1;
                }
            }
        }

        public static void DrawEQTriangleUp(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint cst = Base / 2;
            uint rsy = y;
            uint rsx = x + Base;
            uint lsy = y;
            uint lsx = x;

            for (uint i = x; i <= x + Base; i++)
            {
                lsy = lsy + 1;
                lsx = lsx + 1;

                rsy = rsy + 1;
                rsx = rsx - 1;
                VGA.dbuffer[(y * VGA.ScreenWidth) + i] = Color;
                if (p != cst)
                {
                    VGA.dbuffer[(lsy * VGA.ScreenWidth) + lsx] = Color;
                    VGA.dbuffer[(rsy * VGA.ScreenWidth) + rsx] = Color;
                    p = p + 1;
                }
            }
        }

        public static void DrawEQTriangleLeft(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint cst = Base / 2;
            uint rsy = y + Base;
            uint rsx = x;
            uint lsy = y;
            uint lsx = x;

            for (uint i = y; i <= y + Base; i++)
            {

                VGA.dbuffer[(i * VGA.ScreenWidth) + x] = Color;
                lsx = lsx + 1;
                lsy = lsy + 1;

                rsx = rsx + 1;
                rsy = rsy - 1;

                if (p != cst)
                {
                    VGA.dbuffer[(lsy * VGA.ScreenWidth) + lsx] = Color;
                    VGA.dbuffer[(rsy * VGA.ScreenWidth) + rsx] = Color;
                    p = p + 1;
                }
            }
        }

        public static void DrawEQTriangleRight(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint cst = Base / 2;
            uint rsy = y + Base;
            uint rsx = x;
            uint lsy = y;
            uint lsx = x;

            for (uint i = y; i <= y + Base; i++)
            {
                VGA.dbuffer[(i * VGA.ScreenWidth) + x] = Color;
                lsx = lsx - 1;
                lsy = lsy + 1;

                rsx = rsx - 1;
                rsy = rsy - 1;

                if (p != cst)
                {
                    VGA.dbuffer[(lsy * VGA.ScreenWidth) + lsx] = Color;
                    VGA.dbuffer[(rsy * VGA.ScreenWidth) + rsx] = Color;
                    p = p + 1;
                }
            }
        }

        public static void DrawFillEQTriangleDown(uint x, uint y, uint Base, byte Color)
        {
            ///Use One Loop to improve speed
            uint p = 0;
            uint lsx = x;
            uint lsy = y;
            p = 1;

            for (uint j = 0; j <= (Base + 1) / 2; j++)
            {
                for (uint i = lsx; i < x + p; i++)
                {
                    VGA.dbuffer[(lsy * VGA.ScreenWidth) + i] = Color;
                }
                if (p == Base)
                {
                    break;
                }
                lsy = lsy + 1;
                lsx = lsx - 2;
                p = p + 2;
            }
        }

        public static void DrawFillEQTriangleUp(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint lsx = x;
            uint lsy = y;
            p = 1;

            for (uint j = 0; j <= (Base + 1) / 2; j++)
            {
                for (uint i = lsx; i < x + p; i++)
                {
                    VGA.dbuffer[(lsy * VGA.ScreenWidth) + i] = Color;
                }
                if (p == Base)
                {
                    break;
                }
                lsy = lsy - 1;
                lsx = lsx - 2;
                p = p + 2;
            }
        }

        public static void DrawFillEQTriangleRight(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint lsx = x;
            uint lsy = y;
            p = 1;

            for (uint j = 0; j <= (Base + 1) / 2; j++)
            {
                for (uint i = lsy; i < y + p; i++)
                {
                    VGA.dbuffer[(i * VGA.ScreenWidth) + lsx] = Color;
                }
                if (p == Base)
                {
                    break;
                }
                lsy = lsy - 2;
                lsx = lsx + 1;
                p = p + 2;
            }
        }

        public static void DrawFillEQTriangleLeft(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint lsx = x;
            uint lsy = y;
            p = 1;

            for (uint j = 0; j <= (Base + 1) / 2; j++)
            {
                for (uint i = lsy; i < y + p; i++)
                {
                    VGA.dbuffer[(i * VGA.ScreenWidth) + lsx] = Color;
                }
                if (p == Base)
                {
                    break;
                }
                lsy = lsy - 2;
                lsx = lsx - 1;
                p = p + 2;
            }
        }

        public static void DrawRATriangle(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint lsy = y;
            uint lsx = x;
            p = y;
            for (uint i = x; i < x + Base; i++)
            {
                lsy = lsy - 1;
                lsx = lsx + 1;
                VGA.dbuffer[(y * VGA.ScreenWidth) + i] = Color;
                VGA.dbuffer[(p * VGA.ScreenWidth) + (x + Base)] = Color;
                VGA.dbuffer[(lsy * VGA.ScreenWidth) + lsx] = Color;
   
                p = p - 1;
            }

        }

        public static void DrawLATriangle(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint rsy = y;
            uint rsx = x + Base;
            p = y;
            for (uint i = x; i < x + Base; i++)
            {
                rsy = rsy - 1;
                rsx = rsx - 1;
                 VGA.SetPixel(i, y, (uint)(Color));
                 VGA.SetPixel(x , p, (uint)(Color));
                 VGA.SetPixel(rsx, rsy, (uint)(Color));

                 VGA.dbuffer[(y * VGA.ScreenWidth) + i] = Color;
                 VGA.dbuffer[(p * VGA.ScreenWidth) + x] = Color;
                 VGA.dbuffer[(rsy * VGA.ScreenWidth) + rsx] = Color;

                p = p - 1;
            }

        }

        public static void DrawTLATriangle(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint rsy = y;
            uint rsx = x + Base;
            p = y;
            for (uint i = x; i < x + Base; i++)
            {
                rsy = rsy + 1;
                rsx = rsx - 1;
                 VGA.SetPixel(i, y, (uint)(Color));
                 VGA.SetPixel(x, p, (uint)(Color));
                 VGA.SetPixel(rsx, rsy, (uint)(Color));

                 VGA.dbuffer[(y * VGA.ScreenWidth) + i] = Color;
                 VGA.dbuffer[(p * VGA.ScreenWidth) + x] = Color;
                 VGA.dbuffer[(rsy * VGA.ScreenWidth) + rsx] = Color;

                p = p + 1;
            }
        }

        public static void DrawTRATriangle(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint lsy = y;
            uint lsx = x;
            p = y;
            for (uint i = x; i < x + Base; i++)
            {
                lsy = lsy + 1;
                lsx = lsx + 1;
                 VGA.dbuffer[(y * VGA.ScreenWidth) + i] = Color;
                 VGA.dbuffer[(p * VGA.ScreenWidth) + (x + Base)] = Color;
                 VGA.dbuffer[(lsy * VGA.ScreenWidth) + lsx] = Color;
                p = p + 1;
            }
        }

        public static void DrawFillLATriangle(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint rsy = y;

            p = 1;
            for (int j = 0; j < Base; j++)
            {
                for (uint i = x; i < x + p; i++)
                {
                    VGA.dbuffer[(rsy * VGA.ScreenWidth) + i] = Color;
                }
                p = p + 1;
                rsy = rsy + 1;
            }
        }

        public static void DrawFillTRATriangle(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint rsy = y;

            p = 1;
            for (int j = 0; j < Base; j++)
            {
                for (uint i = x - Base; i < x - p; i++)
                {
                    VGA.dbuffer[(rsy * VGA.ScreenWidth) + i] = Color;
                }
                p = p + 1;
                rsy = rsy + 1;
            }

        }

        public static void DrawFillTLATriangle(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint rsy = y;
            p = 1;
            for (int j = 0; j < Base; j++)
            {
                for (uint i = x; i < x + p; i++)
                {
                    VGA.dbuffer[(rsy * VGA.ScreenWidth) + i] = Color;
                }
                p = p + 1;
                rsy = rsy - 1;//When y is zero gives problems
            }

        }

        public static void DrawFillRATriangle(uint x, uint y, uint Base, byte Color)
        {
            //Use One Loop to improve speed
            uint p = 0;
            uint rsy = y;
            uint rsx = x;
            p = 1;
            for (int j = 0; j < Base; j++)
            {
                for (uint i = rsx; i < rsx + p; i++)
                {
                    VGA.dbuffer[(rsy * VGA.ScreenWidth) + i] = Color;
                }

                p = p + 1;
                rsx = rsx - 1;
                rsy = rsy + 1;
            }
        }



        //Window Drawing Functions

        public static void DrawNovaWnd(uint x, uint y, uint length, uint width, byte BorderColor)
        {
            //Function Buttons
            DrawRectangle((x + length) - 30, y - 10, 30, 10, 8);
            DrawFillRectangle((x + length) - 29, y - 9, 29, 8, BorderColor);

            //Seperators
            DrawVerticalLine((x + length) - 10, y - 9, 10, 1, 8);
            DrawVerticalLine((x + length) - 20, y - 9, 10, 1, 8);

            DrawRectangle(x, y, length, width, 8);
            DrawFillRectangle(x + 1, y + 1, length - 1, width - 2, BorderColor);
        }
     
    }
}
